package org.studiox.graph.persistence.mybatis.tk.mapper;

import org.apache.ibatis.annotations.*;
import org.studiox.graph.persistence.mybatis.tk.base.BaseGraphMapper;
import org.studiox.graph.persistence.mybatis.tk.domain.GraphEdgeDO;

import java.util.List;

public interface GraphEdgeMapper extends BaseGraphMapper<GraphEdgeDO> {

  @Select("select id from graph_edge")
  List<Long> getGraphEdgeIds();

  @Select("select min(id) from graph_edge group by source_vertex_uniq,target_vertex_uniq")
  List<Long> getGraphUniqueMinEdgeIds();

  @Select("select max(id) from graph_edge group by source_vertex_uniq,target_vertex_uniq")
  List<Long> getGraphUniqueMaxEdgeIds();

  @Select(
      "select count(*) from graph_edge where source_vertex_uniq=#{sourceVertexUniq} and target_vertex_uniq=#{targetVertexUniq}")
  Long getGraphEdgeContentSize(
      @Param("sourceVertexUniq") String sourceVertexUniq,
      @Param("targetVertexUniq") String targetVertexUniq);

  @Select(
      "select content from graph_edge where source_vertex_uniq=#{sourceVertexUniq} and target_vertex_uniq=#{targetVertexUniq} order by create_time asc")
  List<String> getGraphEdgeContents(
      @Param("sourceVertexUniq") String sourceVertexUniq,
      @Param("targetVertexUniq") String targetVertexUniq);

  @Select(
      "select * from graph_edge where source_vertex_uniq=#{sourceVertexUniq} and target_vertex_uniq=#{targetVertexUniq} order by create_time asc limit 1")
  @Results(
      id = "graphEdgeDOMap",
      value = {
        @Result(id = true, column = "id", property = "id"),
        @Result(column = "content", property = "content"),
        @Result(column = "content_md5", property = "contentMd5"),
        @Result(column = "type", property = "type"),
        @Result(column = "owner", property = "owner"),
        @Result(column = "source_vertex_uniq", property = "sourceVertexUniq"),
        @Result(column = "target_vertex_uniq", property = "targetVertexUniq"),
        @Result(column = "janus_edge_id", property = "janusEdgeId"),
        @Result(column = "neo4j_edge_id", property = "neo4jEdgeId"),
        @Result(column = "nebula_edge_id", property = "nebulaEdgeId"),
        @Result(column = "source_janus_vertex_id", property = "sourceJanusVertexId"),
        @Result(column = "target_janus_vertex_id", property = "targetJanusVertexId"),
        @Result(column = "source_neo4j_vertex_id", property = "sourceNeo4jVertexId"),
        @Result(column = "target_neo4j_vertex_id", property = "targetNeo4jVertexId"),
        @Result(column = "source_nebula_vertex_id", property = "sourceNebulaVertexId"),
        @Result(column = "target_nebula_vertex_id", property = "targetNebulaVertexId"),
        @Result(column = "deleted", property = "deleted"),
        @Result(column = "create_time", property = "createTime"),
        @Result(column = "update_time", property = "updateTime")
      })
  GraphEdgeDO getOneGraphEdgeDoBySourceTargetUniq(
      @Param("sourceVertexUniq") String sourceVertexUniq,
      @Param("targetVertexUniq") String targetVertexUniq);

  @Select(
      "select id from graph_edge where (length(trim(content_md5))=0 or content_md5=MD5(#{content})) and source_vertex_uniq=#{sourceVertexUniq} and target_vertex_uniq=#{targetVertexUniq} and content=#{content} limit 1")
  Long getGraphEdgeId(
      @Param("content") String content,
      @Param("sourceVertexUniq") String sourceVertexUniq,
      @Param("targetVertexUniq") String targetVertexUniq);

  @Update("update graph_edge set content_md5=MD5(content) where id=#{id}")
  void updateGraphEdgeContentMd5(@Param("id") Long id);

  @Update("update graph_edge set content_md5=MD5(content) where length(trim(content_md5))=0")
  void updateAllGraphEdgeContentMd5();

  @Update("update graph_edge set janus_edge_id=#{janusEdgeId} where id=#{id}")
  void updateJanusEdgeId(@Param("id") Long id, @Param("janusEdgeId") String janusEdgeId);

  @Update(
      "update graph_edge set janus_edge_id=#{janusEdgeId},source_janus_vertex_id=#{sourceJanusVertexId},target_janus_vertex_id=#{targetJanusVertexId} where id=#{id}")
  void updateJanusEdgeIdAndSourceTargetVertexId(
      @Param("id") Long id,
      @Param("janusEdgeId") String janusEdgeId,
      @Param("sourceJanusVertexId") Long sourceJanusVertexId,
      @Param("targetJanusVertexId") Long targetJanusVertexId);

  @Update("update graph_edge set neo4j_edge_id=#{neo4jEdgeId} where id=#{id}")
  void updateNeo4jEdgeId(@Param("id") Long id, @Param("neo4jEdgeId") Long neo4jEdgeId);

  @Update(
      "update graph_edge set neo4j_edge_id=#{neo4jEdgeId},source_neo4j_vertex_id=#{sourceNeo4jVertexId},target_neo4j_vertex_id=#{targetNeo4jVertexId} where id=#{id}")
  void updateNeo4jEdgeIdAndSourceTargetVertexId(
      @Param("id") Long id,
      @Param("neo4jEdgeId") Long neo4jEdgeId,
      @Param("sourceNeo4jVertexId") Long sourceNeo4jVertexId,
      @Param("targetNeo4jVertexId") Long targetNeo4jVertexId);

  @Update("update graph_edge set nebula_edge_id=#{nebulaEdgeId} where id=#{id}")
  void updateNebulaEdgeId(@Param("id") Long id, @Param("nebulaEdgeId") String nebulaEdgeId);

  @Update(
      "update graph_edge set nebula_edge_id=#{nebulaEdgeId},source_nebula_vertex_id=#{sourceNebulaVertexId},target_nebula_vertex_id=#{targetNebulaVertexId} where id=#{id}")
  void updateNebulaEdgeIdAndSourceTargetVertexId(
      @Param("id") Long id,
      @Param("nebulaEdgeId") String nebulaEdgeId,
      @Param("sourceNebulaVertexId") Long sourceNebulaVertexId,
      @Param("targetNebulaVertexId") Long targetNebulaVertexId);

  @Update(
      "update graph_edge set source_janus_vertex_id=#{sourceJanusVertexId} where source_vertex_uniq=#{sourceVertexUniq}")
  void updateSourceJanusVertexId(
      @Param("sourceVertexUniq") String sourceVertexUniq,
      @Param("sourceJanusVertexId") Long sourceJanusVertexId);

  @Update(
      "update graph_edge set target_janus_vertex_id=#{targetJanusVertexId} where target_vertex_uniq=#{targetVertexUniq}")
  void updateTargetJanusVertexId(
      @Param("targetVertexUniq") String targetVertexUniq,
      @Param("targetJanusVertexId") Long targetJanusVertexId);

  @Update(
      "update graph_edge a set source_janus_vertex_id=(select janus_vertex_id from graph_vertex b where a.source_vertex_uniq=b.uniq);")
  void updateAllSourceJanusVertexId();

  @Update(
      "update graph_edge a set target_janus_vertex_id=(select janus_vertex_id from graph_vertex b where a.target_vertex_uniq=b.uniq);")
  void updateAllTargetJanusVertexId();

  @Update(
      "update graph_edge a "
          + "inner join graph_vertex b on a.source_vertex_uniq=b.uniq "
          + "inner join graph_vertex c on a.target_vertex_uniq=c.uniq "
          + "set a.source_janus_vertex_id=b.janus_vertex_id,a.target_janus_vertex_id=c.janus_vertex_id;")
  void updateAllSourceTargetJanusVertexId();

  @Update(
      "update graph_edge set source_neo4j_vertex_id=#{sourceNeo4jVertexId} where source_vertex_uniq=#{sourceVertexUniq}")
  void updateSourceNeo4jVertexId(
      @Param("sourceVertexUniq") String sourceVertexUniq,
      @Param("sourceNeo4jVertexId") Long sourceNeo4jVertexId);

  @Update(
      "update graph_edge set target_neo4j_vertex_id=#{targetNeo4jVertexId} where target_vertex_uniq=#{targetVertexUniq}")
  void updateTargetNeo4jVertexId(
      @Param("targetVertexUniq") String targetVertexUniq,
      @Param("targetNeo4jVertexId") Long targetNeo4jVertexId);

  @Update(
      "update graph_edge a set source_neo4j_vertex_id=(select neo4j_vertex_id from graph_vertex b where a.source_vertex_uniq=b.uniq);")
  void updateAllSourceNeo4jVertexId();

  @Update(
      "update graph_edge a set target_neo4j_vertex_id=(select neo4j_vertex_id from graph_vertex b where a.target_vertex_uniq=b.uniq);")
  void updateAllTargetNeo4jVertexId();

  @Update(
      "update graph_edge a "
          + "inner join graph_vertex b on a.source_vertex_uniq=b.uniq "
          + "inner join graph_vertex c on a.target_vertex_uniq=c.uniq "
          + "set a.source_neo4j_vertex_id=b.neo4j_vertex_id,a.target_neo4j_vertex_id=c.neo4j_vertex_id;")
  void updateAllSourceTargetNeo4jVertexId();

  @Update(
      "update graph_edge set source_nebula_vertex_id=#{sourceNebulaVertexId} where source_vertex_uniq=#{sourceVertexUniq}")
  void updateSourceNebulaVertexId(
      @Param("sourceVertexUniq") String sourceVertexUniq,
      @Param("sourceNebulaVertexId") Long sourceNebulaVertexId);

  @Update(
      "update graph_edge set target_nebula_vertex_id=#{targetNebulaVertexId} where target_vertex_uniq=#{targetVertexUniq}")
  void updateTargetNebulaVertexId(
      @Param("targetVertexUniq") String targetVertexUniq,
      @Param("targetNebulaVertexId") Long targetNebulaVertexId);

  @Update(
      "update graph_edge a set source_nebula_vertex_id=(select nebula_vertex_id from graph_vertex b where a.source_vertex_uniq=b.uniq);")
  void updateAllSourceNebulaVertexId();

  @Update(
      "update graph_edge a set target_nebula_vertex_id=(select nebula_vertex_id from graph_vertex b where a.target_vertex_uniq=b.uniq);")
  void updateAllTargetNebulaVertexId();

  @Update(
      "update graph_edge a "
          + "inner join graph_vertex b on a.source_vertex_uniq=b.uniq "
          + "inner join graph_vertex c on a.target_vertex_uniq=c.uniq "
          + "set a.source_nebula_vertex_id=b.nebula_vertex_id,a.target_nebula_vertex_id=c.nebula_vertex_id;")
  void updateAllSourceTargetNebulaVertexId();
}
